package com.hehao.java_basic.doc_poi;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.hehao.java_basic.doc_poi.demoEntity.DemoData;
import com.hehao.java_basic.doc_poi.demoEntity.ExportData;
import com.hehao.java_basic.doc_poi.demoEntity.ScaleQuestionOptionDto;
import com.hehao.java_basic.doc_poi.service.PoiService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.compress.utils.Lists;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author hehao
 * @Date 2022/4/13 22:07
 * @Version
 */
@RestController
@RequestMapping("/export")
@Tag(name = "Excel导出")
public class ExcelExportController {

    @Autowired
    private PoiService poiService;

    @Operation(summary = "apache poi方式导出")
    @GetMapping("/excel01")
    public void exportExcel01(HttpServletResponse response) {
        SXSSFWorkbook workbook = poiService.exportExcel01();
        // 输出流
        try {
            response.reset();
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-disposition", "attachment;filename=user_excel_" + System.currentTimeMillis() + ".xlsx");
            ServletOutputStream os = response.getOutputStream();
            workbook.write(os);
            workbook.dispose();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Operation(summary = "easyPoi方式导出")
    @GetMapping("/excel02")
    public void exportExcel02(HttpServletResponse response) {
        SXSSFWorkbook workbook = poiService.exportExcel01();
        // 输出流
        try {
            response.reset();
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-disposition", "attachment;filename=user_excel_" + System.currentTimeMillis() + ".xlsx");
            ServletOutputStream os = response.getOutputStream();
            workbook.write(os);
            workbook.dispose();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Operation(summary = "easyExcel方式导出")
    @GetMapping("/excel03")
    public void exportExcel03(HttpServletResponse response) {
        //XSSFWorkbook workbook = new XSSFWorkbook();
        //Sheet sheet = workbook.createSheet("sheet");
        //WriteSheet sheet = new WriteSheet();
        //sheet.setSheetNo(0);
        //sheet.setSheetName("sheet1");
        try {
            String fileName = "test";
            ServletOutputStream outputStream = response.getOutputStream();
            ExcelWriter excelWriter = EasyExcel.write(outputStream, DemoData.class).build();
            WriteSheet writeSheet = EasyExcel.writerSheet(0,"模板").build();
            for (int i = 0; i < 100; i++) {
                System.out.println("=======第" + i+1 + "次生成数据================");
                List<DemoData> list = getData();
                //ExcelWriter writer = EasyExcelFactory.getWriter(outputStream);
                //writer.write(list, sheet);
                //writer.finish();
                excelWriter.write(list, writeSheet);
            }
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            excelWriter.finish();
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void simpleWrite() {
        // 注意 simpleWrite在数据量不大的情况下可以使用（5000以内，具体也要看实际情况），数据量大参照 重复多次写入

        // 写法1 JDK8+
        // since: 3.0.0-beta1
        String fileName = "test.xlsx";
        // 这里 需要指定写用哪个class去写，然后写到第一个sheet，名字为模板 然后文件流会自动关闭
        // 如果这里想使用03 则 传入excelType参数即可
        EasyExcel.write(fileName, DemoData.class)
                .sheet("模板")
                .doWrite(getData());

        //// 写法2
        //// 这里 需要指定写用哪个class去写，然后写到第一个sheet，名字为模板 然后文件流会自动关闭
        //// 如果这里想使用03 则 传入excelType参数即可
        //EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());
        //
        //// 写法3
        //// 这里 需要指定写用哪个class去写
        //try (ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build()) {
        //    WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
        //    excelWriter.write(data(), writeSheet);
        //}
    }

    private List<DemoData> getData() {
        List<DemoData> list = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            DemoData data = new DemoData();
            data.setString("字sdfsdf讽德诵功地方是kjdlfsp个就是怕拦截到了付款时间独立访客加拉克世纪东方卢卡申科时间到了开发时间够哦序偶ICvuoiv 符串" + i);
            data.setDate(new Date());
            data.setDoubleData(0.56);
            list.add(data);
        }
        return list;
    }

    @Operation(summary = "easyExcel动态表头方式导出")
    @GetMapping("/excel04")
    public void exportExcel04(HttpServletResponse response) {
        // 模拟数据
        List<ExportData> dataList = new ArrayList<>();
        ExportData data1 = new ExportData(1, "Type A", "Title 1", Arrays.asList(
                new ScaleQuestionOptionDto("Option1", "Content1"),
                new ScaleQuestionOptionDto("Option2", "Content2")
        ),null);
        ExportData data2 = new ExportData(2, "Type B", "Title 2", Arrays.asList(
                new ScaleQuestionOptionDto("Option3", "Content3"),
                new ScaleQuestionOptionDto("Option4", "Content4")
        ),null);
        dataList.add(data1);
        dataList.add(data2);

        List<ScaleQuestionOptionDto> options = new ArrayList<>();
        options.add(new ScaleQuestionOptionDto("A", "Option A Content"));
        options.add(new ScaleQuestionOptionDto("B", "Option B Content"));
        options.add(new ScaleQuestionOptionDto("C", "Option C Content"));


        try {
            String fileName = "test";
            ServletOutputStream outputStream = response.getOutputStream();
            ExcelWriter excelWriter = EasyExcel.write(outputStream, ScaleQuestionOptionDto.class).build();
            WriteSheet writeSheet = EasyExcel.writerSheet(0,"模板").build();

            // 创建ExcelWriterBuilder
            ExcelWriterBuilder writerBuilder = EasyExcel.write(outputStream, ScaleQuestionOptionDto.class);

            // 设置表头
            List<String> headers = options.stream()
                    .map(ScaleQuestionOptionDto::getOption)
                    .collect(Collectors.toList());
            List<List<String>> list = Lists.newArrayList();
            list.add(headers);
            writerBuilder.head(list);

            // 设置内容
            List<List<String>> content = options.stream()
                    .map(option -> Collections.singletonList(option.getContent()))
                    .collect(Collectors.toList());
            writerBuilder.sheet().doWrite(content);

            // 写入Excel文件
//            writerBuilder.build().write(content);

            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            excelWriter.finish();
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
